package com.gipson.amc.service.basicdata;

import com.baomidou.mybatisplus.core.injector.methods.DeleteBatchByIds;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dsbj.common.msg.ResponseMessage;
import com.gipson.amc.entity.*;
import com.gipson.amc.mapper.RoleAuthorityMapper;
import com.gipson.amc.mapper.RoleMapper;
import com.gipson.amc.mapper.UserRoleMapper;
import com.gipson.amc.utils.security.ShiroUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * <p>
 * 角色 服务实现类
 * </p>
 *
 * @author xsyuan
 * @since 2020-03-27
 */
@Service
public class RoleService extends ServiceImpl<RoleMapper, Role> {

    @Resource
    private RoleAuthorityService roleAuthorityService;

    @Resource
    private UserService userService;

    public List<Role> getRolesByUsername(String username) {
        List<Role> roleList = baseMapper.getRolesByUsername(username);
        return roleList;
    }

    @Transactional
    public void addRole(Role role) {
        save(role);
    }

    /**
     * 分页查询
     * @return
     */
    public IPage<Role> selectPage(Role role, PageByDataTable pageByDataTable){
        Page<Role> page=new Page<Role>().setSize(pageByDataTable.getPagesize()).setCurrent(pageByDataTable.getPageindex());
        page = (Page<Role>) baseMapper.queryPageData(page,role,pageByDataTable);
        if(CollectionUtils.isNotEmpty(page.getRecords())){
            fillExtraValue(page.getRecords());
        }
        return page;
    }

    private void fillExtraValue(List<Role> records) {
        List<String> userIds = Stream.of(
                records.stream().map(x -> x.getCreateUser()).collect(Collectors.toList()),
                records.stream().map(x -> x.getUpdateUser()).collect(Collectors.toList()))
                .flatMap(Collection::stream).distinct()
                .filter(x->StringUtils.isNotEmpty(x))
                .collect(Collectors.toList());
        Map<String, User> map = userService.mapUserByIds(userIds);
        for (Role role : records) {
            role.setCreateUserName(map.containsKey(role.getCreateUser()) ? map.get(role.getCreateUser()).getName() : "");
            role.setUpdateUserName(map.containsKey(role.getUpdateUser()) ? map.get(role.getUpdateUser()).getName() : "");
        }
    }

    @Transactional
    public ResponseMessage saveRole(Role role,String nodes) {
        String msg = "";
        List<Role> checkRoleName = list(Wrappers.<Role>lambdaQuery()
                .eq(Role::getRoleName, role.getRoleName().trim())
                .eq(Role::getApplicationId, role.getApplicationId())
        );
        if (CollectionUtils.isNotEmpty(checkRoleName)) {
            msg = "角色名称已重复！";
            return ResponseMessage.error(msg);
        }
        List<Role> checkRoleCode = list(Wrappers.<Role>lambdaQuery()
                .eq(Role::getRoleCode, role.getRoleCode().trim())
                .eq(Role::getApplicationId, role.getApplicationId())
        );
        if (CollectionUtils.isNotEmpty(checkRoleCode)) {
            msg = "角色编号已重复！";
            return ResponseMessage.error(msg);
        }
        //保存到角色表
        User user = ShiroUtils.getCurrentUser();
        role.setCreateUser(user.getId());
        role.setCreateTime(new Date());
        save(role);
        //保存到角色权限表
        if(StringUtils.isNotBlank(nodes)){
            String[] nodes_arr = nodes.split(",");
            for (int i = 0; i <nodes_arr.length ; i++) {
                if(!nodes_arr[i].equals("0")){
                    RoleAuthority roleAuthority = new RoleAuthority();
                    roleAuthority.setRoleId(role.getId());
                    roleAuthority.setAuthorityId(nodes_arr[i]);
                    roleAuthorityService.save(roleAuthority);
                }
            }
        }
        msg = "新增成功！";
        return ResponseMessage.ok(null,msg);
    }

    @Transactional
    public ResponseMessage updateRole(Role role){
        String msg = "";
        List<Role> checkRoleName = list(Wrappers.<Role>lambdaQuery()
                .eq(Role::getRoleName, role.getRoleName().trim())
                .eq(Role::getApplicationId, role.getApplicationId())
                .ne(Role::getId, role.getId())
        );
        if (CollectionUtils.isNotEmpty(checkRoleName)) {
            msg = "角色名称已重复！";
            return ResponseMessage.error(msg);
        }
        List<Role> checkRoleCode = list(Wrappers.<Role>lambdaQuery()
                .eq(Role::getRoleCode, role.getRoleCode().trim())
                .eq(Role::getApplicationId, role.getApplicationId())
                .ne(Role::getId, role.getId())
        );
        if (CollectionUtils.isNotEmpty(checkRoleCode)) {
            msg = "角色编号已重复！";
            return ResponseMessage.error(msg);
        }
        //保存到角色表
        User user = ShiroUtils.getCurrentUser();
        role.setUpdateTime(new Date());
        role.setUpdateUser(user.getId());
        updateById(role);
        msg = "修改成功！";
        return ResponseMessage.ok(null,msg);
    }

    @Transactional
    public ResponseMessage saveRoleAuthority(String id,String nodes) {
        //根据roleCode删除角色权限
        roleAuthorityService.deleteByRoleId(id);
        //删除成功，重新添加
        //保存到角色权限表
        if(StringUtils.isNotBlank(nodes)){
            String[] nodes_arr = nodes.split(",");
            for (int i = 0; i <nodes_arr.length ; i++) {
                if(!nodes_arr[i].equals("0")){
                    RoleAuthority roleAuthority = new RoleAuthority();
                    roleAuthority.setRoleId(id);
                    roleAuthority.setAuthorityId(nodes_arr[i]);
                    roleAuthorityService.save(roleAuthority);
                }
            }
        }
        return ResponseMessage.ok("修改权限成功！");
    }

    @Transactional
    public ResponseMessage deleteOne(String id) {
        //根据角色编码删除角色对应的权限
        roleAuthorityService.deleteByRoleId(id);
        //根据角色ID删除用户角色
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("roleIds",  StringUtils.split(id, ","));
        baseMapper.deleteUserRoleByRoleId(map);
        //根据角色ID删除角色
        baseMapper.deleteById(id);
        return ResponseMessage.ok("删除成功！");
    }

    @Transactional
    public ResponseMessage delBatch(String ids) {
        //根据角色编码删除角色对应的权限
        roleAuthorityService.deleteByRoleIds(StringUtils.join(ids,","));
        String[] arr = StringUtils.split(ids, ",");
        List<String> idsList = Arrays.asList(arr);
        //根据角色ID删除用户角色
        Map<String, Object> map2 = new HashMap<String, Object>();
        map2.put("roleIds", StringUtils.split(ids, ","));
        baseMapper.deleteUserRoleByRoleId(map2);
        //根据角色ID删除角色
        baseMapper.deleteBatchIds(idsList);
        return ResponseMessage.ok("删除成功！");
    }

}
